/***************************************************************************
 *   Copyright (C) 2008 by Goliash   *
 *   goliash@goliash.net   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

 #include <QtGui>
 #include "images.h"
#include "rename_medium_dialog.h"

 #include "mainwindow.h"

MainWindow::MainWindow(QMainWindow *parent)
     : QMainWindow(parent)
 {
	ui.setupUi(this);

	connect(ui.tableView, SIGNAL(clicked (QModelIndex)), this, SLOT(changeDetail(QModelIndex)));
	connect(ui.tableView, SIGNAL(doubleClicked (QModelIndex)), this, SLOT(changeFolder(QModelIndex)));
	connect(ui.treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(changeMedium(QModelIndex)));
	connect(ui.treeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
	connect(ui.tableView->horizontalHeader(), SIGNAL(sectionClicked (int)), this, SLOT(sortTableView(int)));
	connect(ui.upButton, SIGNAL(clicked()), this, SLOT(goToParentFolder()));

	db = QSqlDatabase::addDatabase("QSQLITE");
	readSettings();
 }

void MainWindow::showData()
{
	// doresit
	if(!ui.dockData->isVisible()) { ui.actionShow_dock_Data->setChecked(true); ui.dockData->setVisible(true); }
	if(!ui.dockMedia->isVisible()) { ui.actionShow_dock_Media->setChecked(true); ui.dockMedia->setVisible(true); }
	if(!ui.dockDetail->isVisible()) { ui.actionShow_dock_Details->setChecked(true); ui.dockDetail->setVisible(true); }

	model = new QStandardItemModel(ui.tableView);
	currentMedium = 1;

	setTableView();
	updateTableView(0, 1);
	//QMessageBox::information(this, tr("Information"), tr("SQLite DB successfully connected."));

	/* nefunkcni dolovani ikony ze sqlite databaze
	model = new QStandardItemModel(ui.tableView);
	QSqlQuery query;
	query.exec(QString("SELECT F.id, T.icon, F.name, T.name FROM files F, types T WHERE T.id_type=F.id_type AND id_medium='%1' AND F.in_root='1'").arg(current_medium, 0, 10));
	//model->setRowCount(4);
	model->setColumnCount(4);
	int row = 0;
	while(query.next())
	{
		for (int column = 0; column < 4; ++column) {
			if(column == 1) {
				//QIcon *icon = new QIcon(":/icon-32x32.xpm");

				
				QByteArray array = query.value(1).toByteArray();
				QBuffer buffer(&array);
				QImageReader reader(&buffer, "PNG");
				QImage image = reader.read(); 
				QIcon *icon = new QIcon(QPixmap::fromImage(image));
				/QStandardItem *item = new QStandardItem();
				//item->setIcon(*icon);
				//item->setText("icon");
				QModelIndex *hu = new QModelIndex();
				QModelIndex index = model->index(row, column, *hu);
				model->setData(index, *icon, Qt::DecorationRole);
				//model->setData(index, "huu", Qt::EditRole);
				//model->setItem(row, 3, item);
			}
			else {
				QStandardItem *item = new QStandardItem(QString("%0").arg(query.value(column).toString()));
				model->setItem(row, column, item);
			}
		}
		row ++;
	}

	*/
	
	// naplneni treeView
	//model_tree = new QSqlQueryModel(ui.treeView);
	model_tree = new QStandardItemModel(ui.treeView);
	setTreeView();
	updateTreeView();

	//current_detail = -1;
	//model_detail = new QSqlQueryModel(ui.detailView);
	////model_detail->setQuery(QString("select * from general G where G.id='%1'").arg(current_detail, 0, 10));
	
	//ui.detailView->setModel(model_detail);
	//ui.detailView->show();
}

void MainWindow::setTableView() {

	model->setColumnCount(4);
	model->setHeaderData(1, Qt::Horizontal, tr("File name"), 0);
	model->setHeaderData(2, Qt::Horizontal, tr("File type"), 0);
	model->setHeaderData(3, Qt::Horizontal, tr("Size"), 0);
	currentOrder = "ORDER BY F.id_type, F.name ASC";
	ascOrder = true;

	//ui.tableView->resizeRowsToContents();
	ui.tableView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);

	ui.tableView->setEditTriggers(0);
	ui.tableView->setModel(model);
	ui.tableView->show();
	ui.tableView->setColumnHidden(0, true);
	ui.tableView->setColumnWidth(1, 220);
}

void MainWindow::updateTableView(int parent, bool path) {
	int in_root = 1;
	QSqlQuery query;
	currentFolder = parent;
	int row = 0;	

	// only deleting rows from model
	QModelIndex *par = new QModelIndex();
	model->removeRows(0, model->rowCount(*par), *par);

	if(parent != 0) {
		in_root = 0;
	}

	if(path) updatePath(in_root, 0);
	if(in_root == 0) {
		row = 1;
		// adding extra row for parent dir
		QStandardItem *item = new QStandardItem(QString("%1").arg(-1));
		model->setItem(0, 0, item);
		
		//QStandardItem *item1 = new QStandardItem(QString(".."));
		//model->setItem(0, 1, item1);
		
		QModelIndex index = model->index(0, 1, *par);
		model->setData(index, Images::icon("arrow-up-blue", 12), Qt::DecorationRole);
		model->setData(index, "..", Qt::EditRole);
		
		QStandardItem *item2 = new QStandardItem(QString("Folder"));
		model->setItem(0, 2, item2);
	}
	else {
		row = 0;
	}

	query.exec(QString("SELECT F.id, F.name, T.name, G.size, T.icon FROM files F, types T, general G WHERE T.id_type=F.id_type AND id_medium='%1' AND parent_id='%2' AND F.in_root='%3' AND F.id=G.id %4").arg(currentMedium, 0, 10).arg(parent).arg(in_root).arg(currentOrder));
	qDebug() << query.lastError() << parent;

        QModelIndex index;
	while(query.next())
	{
		for (int column = 0; column < 4; ++column) {
			if(column == 1) {
				//qDebug() << query.value(3).toString();
                                index = model->index(row, column, *par);
				model->setData(index, Images::icon(query.value(4).toString(), 16), Qt::DecorationRole);
				model->setData(index, query.value(column).toString(), Qt::EditRole);
			}
			else if(column == 3) {
				//qDebug() << File::getFormattedSize(query.value(column).toDouble(), 1);
				QStandardItem *item = new QStandardItem(File::getFormattedSize(query.value(column).toDouble(), File::DynamicF));
				model->setItem(row, column, item);
                                index = model->index(row, column, *par);
                                model->setData(index, Qt::AlignRight, Qt::TextAlignmentRole);
			}
			else {
				QStandardItem *item = new QStandardItem(QString("%0").arg(query.value(column).toString()));
				model->setItem(row, column, item);
			}
		}
		row ++;
	}
}

void MainWindow::setTreeView()
{
	ui.treeView->setModel(model_tree);

	//ui.treeView->setColumnHidden(1, true);
	ui.treeView->show();
	//model_tree->setHeaderData(1, Qt::Horizontal, "Name", 0);
	model_tree->setHorizontalHeaderLabels(QStringList(tr("Name")));
}

void MainWindow::updateTreeView()
{
	QModelIndex *par = new QModelIndex();
	model_tree->removeRows(0, model_tree->rowCount(*par), *par);

	QSqlQuery query;
	query.exec(QString("SELECT M.name, M.id FROM media M"));
	//qDebug() << query.lastError();

	int row = 0;
	while(query.next())
	{
		//QIcon *icon = new QIcon(":/cd.xpm");
		qDebug() << query.value(0).toString();

		QStandardItem *item0 = new QStandardItem(query.value(0).toString());
		//item0->setIcon(*icon);
		item0->setIcon(Images::icon("cd"));
		model_tree->setItem(row, 0, item0);
		
		QStandardItem *item1 = new QStandardItem(query.value(1).toString());
		model_tree->setItem(row, 1, item1);

		row++;
	}
	ui.treeView->setColumnHidden(1, true);
}

void MainWindow::on_actionNew_database_activated()
{
	qDebug() << "new db";
	if(db.isOpen()) {
		//DbDialog *db_dial = new DbDialog(this);
		int ret = QMessageBox::information(this, tr("DiskMuster: Info"), tr("Currently you have an open database.\nDo you want to close it a to create the new one?"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);

		if(ret != QMessageBox::Ok) return;
	}

	// creating new db
	QString fileName = QFileDialog::getSaveFileName(this, tr("Create File"), "/home/goliash/download/db.sqlite",
                                tr("Sqlite files (*.sqlite);;All files (*.*)"));
	if(!fileName.isNull()) {
		closeDb();
		newDb(fileName);
	}
}

void MainWindow::on_actionOpen_database_activated()
{
	if(db.isOpen()) {
		int ret = QMessageBox::information(this, tr("DiskMuster"), tr("Currently you have an open database.\nDo you want to close it a to open the next one?"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
		
		if(ret != QMessageBox::Ok) return;
	}

	// opening other db
	QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "/home/goliash/download",
                                tr("Sqlite files (*.sqlite);;All files (*)"));
	if(!fileName.isNull()) {
		qDebug() << "filename je ruzne od ''";
		closeDb();
		openDb(fileName);
	}
}

void MainWindow::on_actionSave_activated()
{
	
}

void MainWindow::on_actionClose_database_activated()
{
	closeDb();
}

void MainWindow::on_actionAbout_activated() {
	QMessageBox::about(this, tr("About Application"),
            tr("The application <b>DiskMuster</b> is an attempt to "
                  "write modern multiplatform open source GUI applications using Qt. "
                  "The purpose is to organize your data storages in the simple database and "
		"to provide you basic information about single files.<br /><br />") +  tr("Version %1<br />").arg(DISKMUSTER_VERSION) + "(c) 2009 Petr Gadula" + "");
		// je treba domyslet verzovani - mrknout do sqliteman zdrojaku
}

void MainWindow::on_actionAbout_Qt_activated() {
	QMessageBox::aboutQt(this, tr("About Qt"));
}

void MainWindow::changeDetail(QModelIndex index) {
	// there is a hidden id in the first column
	current_detail = index.sibling(index.row(), 0).data(0).toInt();

	// delete labels
	activeThumbnail->clear();

	// change labels
	QSqlQuery query;
	QString fileDetail = "";
	query.exec(QString("SELECT T.id_type, G.id, G.size, G.creation_date, G.rights, G.last_change, T.name FROM files F, general G, types T WHERE G.id='%1' AND F.id=G.id AND F.id_type=T.id_type").arg(current_detail));
	if(query.next()) {
		fileDetail = "<h3>" + tr("General information") + "</h3><table>";
		fileDetail += "<tr><td width='150'><b>" + tr("Type") + "</b></td><td>" + query.value(6).toString() + "</td></tr>";
		fileDetail += "<tr><td><b>" + tr("Size") + "</b></td><td>" + File::getFormattedSize(query.value(2).toUInt(), File::DynamicF) + "</td></tr>";
		fileDetail += "<tr><td><b>" + tr("Creation date") + "</b></td><td>" + File::getFormattedDate(query.value(3).toString(), File::StandardDateF) + "</td></tr>";
		fileDetail += "<tr><td><b>" + tr("Last change") + "</b></td><td>" + File::getFormattedDate(query.value(5).toString(), File::StandardDateF) + "</td></tr>";
		fileDetail += "<tr><td><b>" + tr("Rights") + "</b></td><td>" + query.value(4).toString() + "</td></tr>";
		fileDetail += "</table>";
	}
	if(query.value(0).toInt() == File::JPEG) {
		query.exec(QString("SELECT P.id, P.width, P.height, P.depth, P.thumbnail, P.exif FROM files F, pictures P WHERE F.id='%1' AND F.id=P.id").arg(current_detail));
		if(query.next()) {
			fileDetail += "<h3>" + tr("Picture info") + "</h3><table>";
			fileDetail += "<tr><td width='150'><b>" + tr("Geometry") + "</b></td><td>" + query.value(1).toString() + "x" + query.value(2).toString() + "</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Depth") + "</b></td><td>" + query.value(3).toString() + " bits</td></tr>";
			fileDetail += "</table>";
			
			//qDebug() << query.value(5).toInt() << " " << query.value(5).toString();
			if(query.value(5).toString() == "0" | query.value(5).toString() == "-1") {
				fileDetail += "<br /><br />" + tr("No EXIF available") + "<br />";
			}
			else {
				fileDetail += "<h3>EXIF</h3><table>";
				QStringList tokens = query.value(5).toString().split(";");
				for(int j = 0; j < Picture::exifKeys.size()/2; j++) {
					//i = exifData.findKey(Exiv2::ExifKey(Picture::exifKeys[j].toStdString()));
					if(!tokens.at(j).isEmpty())
						fileDetail += "<tr><td width='150'>" + Picture::exifKeys.at(2*j+1) + "</td><td>" + tokens.at(j) + "</td></tr>";
				}
			}

			QPixmap pixmap;
			pixmap.loadFromData(query.value(4).toByteArray());
			activeThumbnail->setPixmap(pixmap);
		}
		else {
			// there is no record in Pictures table
			fileDetail += "<h3>" + tr("Picture info") + "</h3>";
			fileDetail += tr("No picture info available") + "<br />";
		}
	}
	if(query.value(0).toInt() == File::AudioContent) {
		query.exec(QString("SELECT A.id, A.length, A.version, A.layer, A.bitrate, A.freq, A.channel, A.tag_title, A.tag_artist, A.tag_composer, A.tag_orig_artist, A.tag_album, A.tag_genre, A.tag_year, A.tag_track, A.tag_comment, A.tag_encoder FROM files F, audio A WHERE F.id='%1' AND F.id=A.id").arg(current_detail));
		if(query.next()) {
			fileDetail += "<h3>" + tr("Audio info") + "</h3><table>";
			fileDetail += "<tr><td width='150'><b>" + tr("Length") + "</b></td><td>" + query.value(1).toString() + " seconds</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Type") + "</b></td><td>" + query.value(2).toString() + " "+ query.value(3).toString() + " </td></tr>";
			fileDetail += "<tr><td><b>" + tr("Bitrate") + "</b></td><td>" + query.value(4).toString() + " kbit/s</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Frequency") + "</b></td><td>" + query.value(5).toString() + " Hz</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Channels") + "</b></td><td>" + Audio::channelsToString(query.value(6).toInt()) + " </td></tr>";
			fileDetail += "</table>";
			
			fileDetail += "<h3>" + tr("Tag content") + "</h3><table>";
			fileDetail += "<tr><td width='150'><b>" + tr("Title") + "</b></td><td>" + query.value(7).toString() + "</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Artist") + "</b></td><td>" + query.value(8).toString() + "</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Album") + "</b></td><td>" + query.value(11).toString() + "</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Year") + "</b></td><td>" + query.value(13).toString() + "</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Track") + "</b></td><td>" + query.value(14).toString() + "</td></tr>";
			if(query.value(9).toString().size() > 0) fileDetail += "<tr><td><b>" + tr("Composer") + "</b></td><td>" + query.value(9).toString() + "</td></tr>";
			if(query.value(10).toString().size() > 0) fileDetail += "<tr><td><b>" + tr("Original artist") + "</b></td><td>" + query.value(10).toString() + "</td></tr>";
			fileDetail += "<tr><td><b>" + tr("Genre") + "</b></td><td>" + query.value(12).toString() + "</td></tr>";
			if(query.value(15).toString().size() > 0) fileDetail += "<tr><td><b>" + tr("Comment") + "</b></td><td>" + query.value(15).toString() + "</td></tr>";
			if(query.value(16).toString().size() > 0) fileDetail += "<tr><td><b>" + tr("Encoder") + "</b></td><td>" + query.value(16).toString() + "</td></tr>";
			fileDetail += "</table>";
		}
		else {
			// there is no record in Audio table
			fileDetail += "<h3>" + tr("Audio info") + "</h3>";
			fileDetail += tr("No audio info available") + "<br />";
		}
	}
	if(query.value(0).toInt() == File::Text) {
		query.exec(QString("SELECT D.id, D.content, D.all_content FROM files F, documents D WHERE F.id='%1' AND F.id=D.id").arg(current_detail));
		if(query.next()) {
			fileDetail += "<h3>" + tr("File content") + "</h3>";
			fileDetail += "<pre>" + query.value(1).toString() + "</pre>";
			if(!query.value(2).toBool()) fileDetail += "<br /><br />...";
		}
	}
	if(query.value(0).toInt() == File::PDF) {
		query.exec(QString("SELECT D.id, D.content, D.all_content, D.author, D.title, D.subject, D.creator, D.keywords, D.pages FROM files F, documents D WHERE F.id='%1' AND F.id=D.id").arg(current_detail));
		if(query.next()) {
			fileDetail += "<h3>" + tr("Document information") + "</h3><table>";
			if(query.value(3).toString().size() > 0) fileDetail += "<tr><td width='150'><b>" + tr("Author") + "</b></td><td>" + query.value(3).toString() + "</td></tr>";
			if(query.value(4).toString().size() > 0) fileDetail += "<tr><td width='150'><b>" + tr("Title") + "</b></td><td>" + query.value(4).toString() + "</td></tr>";
			if(query.value(5).toString().size() > 0) fileDetail += "<tr><td width='150'><b>" + tr("Subject") + "</b></td><td>" + query.value(5).toString() + "</td></tr>";
			if(query.value(6).toString().size() > 0) fileDetail += "<tr><td width='150'><b>" + tr("Creator") + "</b></td><td>" + query.value(6).toString() + "</td></tr>";
			if(query.value(7).toString().size() > 0) fileDetail += "<tr><td width='150'><b>" + tr("Keywords") + "</b></td><td>" + query.value(7).toString() + "</td></tr>";
			if(query.value(8).toString().size() > 0) fileDetail += "<tr><td width='150'><b>" + tr("Number of pages") + "</b></td><td>" + query.value(8).toInt() + "</td></tr>";
			fileDetail += "</table>";
			fileDetail += "<h3>" + tr("File content") + "</h3><table>";
			fileDetail += "<pre>" + query.value(1).toString() + "</pre>";
			if(!query.value(2).toBool()) fileDetail += "<br /><br />...";
		}
	}
	activeTextInfo->setText(fileDetail);
}

void MainWindow::changeMedium(QModelIndex index) {
	// there is a hidden id in the last column
	currentMedium = index.sibling(index.row(), 1).data(0).toInt();
	current_detail = -1;
	//bool conv;
	//QString id_medium = index.sibling(index.row(), 1).data(0).toString();
	//current_medium = id_medium.toInt(&conv, 10);
	//qDebug() << id_medium;
	
	updateTableView(0, 1);
}

void MainWindow::changeFolder(QModelIndex index) {
	// there is a hidden id in the last column
	int id_file = index.sibling(index.row(), 0).data(0).toInt();
	//QString id_file = index.sibling(index.row(), 0).data(0).toString();
	//qDebug() << id_file;

	if(id_file == -1) {
		goToParentFolder();
		return;
	}	

	// testovani na folder ... (prochazeni adresari)
	QSqlQuery query;
	query.exec(QString("SELECT T.id_type, T.name, F.id, F.name FROM files F, types T WHERE F.id='%1' AND F.id_type=T.id_type").arg(id_file));

	if(query.next()) {
		QString name = query.value(1).toString();
		currentFolder = query.value(2).toInt();
		curFolderName = query.value(3).toString();

		if(name == "Folder") {
			updatePath(id_file, 1);
			updateTableView(id_file, 0);
		}
		else qDebug() << "it's not a folder, sorry";
	}
}

void MainWindow::showFolder(int id, int id_medium)
{
	currentMedium = id_medium;
	updateTableView(id, 1);
}

void MainWindow::sortTableView(int section)
{
	ascOrder = !ascOrder;

	switch(section) {
		case 2:
			currentOrder = "ORDER BY F.id_type";
			break;
		case 3:
			currentOrder = "ORDER BY G.size";
			break;
		default:
			currentOrder = "ORDER BY F.id_type, F.name";
	}
	if(ascOrder) currentOrder.append(" ASC");
	else	currentOrder.append(" DESC");

	updateTableView(currentFolder, 0);
}

QSqlDatabase MainWindow::getDb()
{
	return db;
}

void MainWindow::setMediumToDelete(int id_medium)
{
	mediumToDelete = id_medium;
}

int MainWindow::getMediumToDelete()
{
	return mediumToDelete;
}

// begin slots: file menu
void MainWindow::on_actionAdd_medium_activated()
{
	if(prefs->device != "") {
		AddMediumDialog *amd = new AddMediumDialog(this);
		amd->show();
	
		Medium *medium = new Medium();
		amd->setMedium(medium);
	
		connect(medium, SIGNAL(stateChanged(int)), amd, SLOT(mediumChanged(int)));
	
		// waiting for cd/dvd is not blocking GUI
		ScanThread *th = new ScanThread();
		th->setMedium(medium);
		th->start();
		//medium->scanISO9660();
	}
	else {
		QMessageBox::information(this, tr("DiskMuster: Info"), tr("You haven't set CD/DVD device yet. Go to Preferences/Drives and set your drive first."), QMessageBox::Ok, QMessageBox::Ok);
	}
}

void MainWindow::on_actionFind_activated()
{
	SearchDialog *sd = new SearchDialog(this);
	sd->show();
}

void MainWindow::deleteMedium()
{
	int id = getMediumToDelete();

	// sql command deleting medium from db
	bool ok = getDb().isOpen();// .open();
	if(ok) {
		QSqlQuery query;
		query.prepare("DELETE FROM media WHERE id=:id");
		query.bindValue(":id", id);
		query.exec();
		query.prepare("DELETE FROM general WHERE id IN (SELECT id FROM files WHERE id_medium=:id)");
		query.bindValue(":id", id);
		query.exec();
		query.prepare("DELETE FROM files WHERE id_medium=:id");
		query.bindValue(":id", id);
		query.exec();
		//query.finish();
		qDebug() << query.executedQuery() << query.isActive() <<query.numRowsAffected() << id;
		qDebug() << getDb().lastError().text();
		updateTreeView();
		updateTableView(0, 1);
	}
	else {
		qDebug() << "Somethings's wrong. Database is closed.";
	}
}

void MainWindow::infoMedium()
{
	int id = getMediumToDelete();

	// information about medium from db
	bool ok = getDb().isOpen();// .open();
	if(ok) {
		QSqlQuery query;
		query.prepare("SELECT name, orig_name, added_to_db, create_application, creation_time, exploring_time, size FROM media WHERE id=:id");
		query.bindValue(":id", id);
		query.exec();
		
		//query.finish();
		// tady vytvorit dialogove okno a vypsat informace o mediu
		InfoDialog *info = new InfoDialog();
		info->setData(query);
		info->exec();

		qDebug() << "medium info";
	}
	else {
		qDebug() << "Somethings's wrong. Database is closed.";
	}
}

void MainWindow::renameMedium()
{
	int id = getMediumToDelete();

	bool ok = getDb().isOpen();
	if(ok) {
		RenameMediumDialog *dialog = new RenameMediumDialog(id);
		dialog->exec();

		updateTreeView();
		updateTableView(0, 1);
	}
	else {
		qDebug() << "Somethings's wrong. Database is closed.";
	}
}

void MainWindow::exportMedium()
{
	int id = getMediumToDelete();

	QString fileName = QFileDialog::getSaveFileName(this, tr("Export to File"), "", tr("HTML files (*.html);;All files (*.*)"));
	if(!fileName.isNull()) {
		QFile file(fileName);
		if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
			return;
	
		QTextStream out(&file);
		QSqlQuery query;
		query.exec(QString("SELECT F.name, M.name FROM media M, files F WHERE M.id=%1 AND M.id=F.id_medium").arg(id));

		//qDebug() << query.lastError();
		bool first = true;
		while(query.next()) {
			if(first) {
				out << "<html><head><title>" << query.value(1).toString() << "</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>\n";
				out << "<h1>"<< query.value(1).toString() <<"</h1>";
				first = false;
			}
			out << query.value(0).toString() << "<br />\n";
		}
		out << "</body></html>";
	}
}

void MainWindow::on_actionPreferences_activated()
{
	PreferencesDialog prefs(this);
	prefs.exec();
}

// begin slots: window menu
void MainWindow::on_actionMove_Detail_Dock_activated()
{
	qDebug() << "Move_Detail_Dock_activated, current dock:" << currentDockDetail;
	if(currentDockDetail == "side") {
		// change to down
		setActiveDetailDock("down");
	}
	else {
		// down, change to side
		setActiveDetailDock("side");
	}
}

void MainWindow::on_actionShow_dock_Details_activated() {
	//qDebug() << "burn!" << ui.actionShow_dock_Details->isChecked();
	if(ui.actionShow_dock_Details->isChecked()) {
		// show dock
		activeDockDetail->show();
	}
	else {
		// hide dock
		activeDockDetail->hide();
	}
}

void MainWindow::on_actionShow_dock_Media_activated() {
	if(ui.actionShow_dock_Media->isChecked()) {
		// show dock
		ui.dockMedia->show();
	}
	else {
		// hide dock
		ui.dockMedia->hide();
	}
}

void MainWindow::on_actionShow_dock_Data_activated() {
	if(ui.actionShow_dock_Data->isChecked()) {
		// show dock
		ui.dockData->show();
	}
	else {
		// hide dock
		ui.dockData->hide();
	}
}

void MainWindow::on_dockDetail_visibilityChanged(bool visible) {
	//qDebug() << "burn!" << ui.dockWidget_3->isHidden();
	//if(!visible) ui.actionShow_dock_Details->setChecked(false);
	if(activeDockDetail == ui.dockDetail) ui.actionShow_dock_Details->setChecked(visible);
}

void MainWindow::on_dockDetail2_visibilityChanged(bool visible)
{
	if(activeDockDetail == ui.dockDetail2) ui.actionShow_dock_Details->setChecked(visible);
}

void MainWindow::on_dockMedia_visibilityChanged(bool visible) {
	//qDebug() << "burn!" << ui.dockWidget_3->isHidden();
	if(!visible) ui.actionShow_dock_Media->setChecked(false);
}

void MainWindow::on_dockData_visibilityChanged(bool visible) {
	//qDebug() << "burn!" << ui.dockWidget_3->isHidden();
	if(!visible) ui.actionShow_dock_Data->setChecked(false);
}
// end slots: window menu

void MainWindow::showContextMenu(const QPoint &pos)
{
	// problem je, ze pos je globalni - v celem mainwindow
	//qDebug() << "custom context menu was requested" << ui.treeView->indexAt(pos);// << ui.treeView->pos();
	
	// if something in treeView is selected
	if(ui.treeView->indexAt(pos).row() != -1) {
		changeMedium(ui.treeView->indexAt(pos));
		
		QMenu menu(this);
		QAction *deleteAct = new QAction(tr("&Delete"), this);
		deleteAct->setStatusTip(tr("Delete the medium"));
		deleteAct->setIcon(Images::icon("delete"));
		connect(deleteAct, SIGNAL(triggered()), this, SLOT(deleteMedium()));

		QAction *infoAct = new QAction(tr("&Info"), this);
		infoAct->setStatusTip(tr("Information about medium"));
		infoAct->setIcon(Images::icon("info"));
		connect(infoAct, SIGNAL(triggered()), this, SLOT(infoMedium()));

		//QIcon *renameIcon = new QIcon(":/info.xpm");
		QAction *renameAct = new QAction(tr("&Rename"), this);
		renameAct->setStatusTip(tr("Rename the medium"));
		renameAct->setIcon(Images::icon("rename"));
		connect(renameAct, SIGNAL(triggered()), this, SLOT(renameMedium()));

		QAction *exportAct = new QAction(tr("&Export to HTML"), this);
		exportAct->setStatusTip(tr("Export list of files and folder into HTML file"));
		exportAct->setIcon(Images::icon("rename"));
		connect(exportAct, SIGNAL(triggered()), this, SLOT(exportMedium()));

		// tady je treba jeste vymyslet predani ui.treeView->indexAt(pos) metode deleteMedium
		setMediumToDelete(ui.treeView->indexAt(pos).sibling(ui.treeView->indexAt(pos).row(), 1).data(0).toInt());
		menu.addAction(deleteAct);
		menu.addAction(infoAct);
		menu.addAction(renameAct);
		menu.addAction(exportAct);
		// position of treeView is (9, 85)
		QPoint *point = new QPoint(pos.x() + this->pos().x() + 15, pos.y() + this->pos().y() + 100);
		menu.exec(*point);
		//menu.exec();
	}
}

void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
	// sometimes here can be found default context menu for main window

	/*QMenu menu(this);
	QAction *deleteAct = new QAction(tr("&Delete"), this);
	deleteAct->setStatusTip(tr("Delete the medium"));
     connect(deleteAct, SIGNAL(triggered()), this, SLOT(on_actionAdd_medium_activated()));

	menu.addAction(deleteAct);
	menu.exec(event->globalPos());
	*/
}

void MainWindow::readSettings()
{
	//qDebug() << "reading settings";
	QSettings settings("Software Inc.", "DiskMuster");
	QRect rect = settings.value("geometry", QRect(100, 100, 800, 681)).toRect();
	move(rect.topLeft());
	resize(rect.size());
	//recentFiles = settings.value("recentFiles").toStringList();
	//updateRecentFileActions();


	// according to settings open db
	// now set to always open ../db/db
	closeDb();
	QString lastdb = settings.value("lastdb", "").toString();
	if(!lastdb.isEmpty()) openDb(lastdb);


	// settings with QList didn't work
	QList<int> splitterSizes;
	splitterSizes << settings.value("dockmedia-width", 200).toInt() << settings.value("dockdata-width", 600).toInt() << settings.value("dockdetails-width", 150).toInt();
	ui.splitter->setSizes(splitterSizes);

	splitterSizes.clear();
	splitterSizes << settings.value("dockmedia-height", 400).toInt() << settings.value("dockdetails-height", 200).toInt();
	ui.splitter_2->setSizes(splitterSizes);

	setActiveDetailDock(settings.value("dockdetails", "down").toString());

	prefs = Preferences::instance();
}

void MainWindow::writeSettings()
{
	//qDebug() << "writing settings";
	QSettings settings("Software Inc.", "DiskMuster");
	settings.setValue("geometry", geometry());
	QString lastdb = "";
	if(db.isOpen()) lastdb = db.databaseName();
	settings.setValue("lastdb", lastdb);
	//settings.setValue("recentFiles", recentFiles);

	settings.setValue("dockmedia-width", ui.splitter->sizes()[0]);
	settings.setValue("dockdata-width", ui.splitter->sizes()[1]);
	settings.setValue("dockdetails-width", ui.splitter->sizes()[2]);

	settings.setValue("dockmedia-height", ui.splitter_2->sizes()[0]);
	settings.setValue("dockdetails-height", ui.splitter_2->sizes()[1]);

	settings.setValue("dockdetails", currentDockDetail);

	Preferences::deleteInstance();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
	if (true) {
		writeSettings();
		event->accept();
	} else {
		event->ignore();
	}
}

void MainWindow::closeDb()
{
	ui.dockData->setVisible(false);
	ui.dockMedia->setVisible(false);
	ui.dockDetail->setVisible(false);
	//model_tree->clear();
	//model->clear();
	// muze se stat, ze neni model jeste inicializovany
	db.close();
}

// novy soubor, otevreni databaze, nahrani tabulek a zakladnich dat - typy atd.
void MainWindow::newDb(QString fileName)
{
	/*
		if (!spreadsheet->writeFile(fileName)) {
			statusBar()->showMessage(tr("Saving canceled"), 2000);
			return false;
		}
		setCurrentFile(fileName);
		statusBar()->showMessage(tr("File saved"), 2000);
		return true;
	*/

	QFile file(fileName);
	if (!file.open(QIODevice::WriteOnly)) {
		
		return;
	}
	db.setDatabaseName(fileName);
	qDebug() << db.open();
	
	// creating tables
	db.transaction();
	QSqlQuery query;

	QStringList table_names;
	table_names << "general" << "archives" << "audio" << "video" << "documents" << "pictures" << "types" << "media" << "files";
	
	QStringList bodies;
	bodies 
		<< "id INTEGER PRIMARY KEY NOT NULL,size REAL,creation_date INTEGER,rights TEXT,last_change INTEGER"
		<< "'id' INTEGER PRIMARY KEY NOT NULL,'compression_rate' REAL,'comment' TEXT"
		<< "'id' INTEGER PRIMARY KEY NOT NULL,'length' INTEGER,'version' TEXT,'layer' TEXT,'bitrate' INTEGER,'freq' INTEGER,'channel' INTEGER,'tag_title' TEXT,'tag_artist' TEXT,'tag_composer' TEXT,'tag_orig_artist' TEXT,'tag_album' TEXT,'tag_genre' TEXT,'tag_year' INTEGER,'tag_track' INTEGER,'tag_comment' TEXT,'tag_encoder' TEXT"
		<< "'id' INTEGER PRIMARY KEY NOT NULL,'width' INTEGER,'height' INTEGER,'length' INTEGER,'fps' INTEGER,'frames' INTEGER,'container' TEXT,'video_codec' TEXT,'video_bitrate' INTEGER,'audio_codec' TEXT,'audio_bitrate' INTEGER,'audio_channels' INTEGER,'audio_freq' INTEGER,'thumbnail' BLOB"
		<< "'id' INTEGER PRIMARY KEY,'author' TEXT,'content' TEXT,'all_content' INTEGER,'title' TEXT,'subject' TEXT,'keywords' TEXT,'creator' TEXT,'pages' INTEGER"
		<< "'id' INTEGER,'width' INTEGER,'height' INTEGER,'depth' INTEGER,'thumbnail' BLOB,'exif' TEXT,'size_in_db' INTEGER"
		<< "'id_type' INTEGER PRIMARY KEY AUTOINCREMENT,'name' TEXT,'comment' TEXT,'icon' TEXT"
		<< "'id' INTEGER PRIMARY KEY AUTOINCREMENT,'name' TEXT,'orig_name' TEXT,'size' INTEGER,'filesystem' INTEGER,'added_to_db' INTEGER,'size_in_db' INTEGER,'comment' TEXT,'exploring_time' INTEGER,'create_application' TEXT,'creation_time' TEXT"
		<< "'id' INTEGER PRIMARY KEY AUTOINCREMENT,'name' TEXT,'parent_id' INTEGER DEFAULT (0),'id_type' INTEGER,'in_root' INTEGER DEFAULT (1),'id_medium' INTEGER DEFAULT (0)";

	for(int i = 0; i < bodies.size(); i++) {
		query.prepare(QString("CREATE TABLE %1 (%2);").arg(table_names[i]).arg(bodies[i]));
		if (!query.exec())
			qDebug() << query.lastError() << query.lastQuery();
	}
	db.commit();

	// batch insert - file types
	query.prepare("INSERT INTO types (name, comment, icon) VALUES (?, ?, ?)");

	QVariantList names;
	names << "Folder" << "JPEG"<< "Text" << "Archive" << "File" << "Test" << "PNG" << "AudioContent" << "PDF";
	query.addBindValue(names);

	QVariantList comment;
	comment << "folder" << "image in JPEG" << "clear text" << "archive" << "unknown file type" << "test" << "image in PNG" << "audio file" << "PDF file";
	query.addBindValue(comment);

	QVariantList icon;
	icon << "folder" << "jpeg" << "txt" << "archive" << "file" << QVariant(QVariant::String) << "png" << "audio" << "pdf";
	query.addBindValue(icon);
	
	if (!query.execBatch())
		qDebug() << query.lastError();

	showData();
}

void MainWindow::openDb(QString fileName)
{
	qDebug() << "opening the db";
	db.setDatabaseName(fileName);

	if(db.open()) {
		showData();
	}
	else
	{
		QMessageBox::information(this, tr("Information"), tr("Connection to SQLite DB failed."));
	}
}

int MainWindow::getSelectedMediumId()
{
	if(ui.treeView->selectionModel()->hasSelection()) {
		//qDebug() << ui.treeView->item(ui.treeView->selectionModel()->selectedRows()[0], 0) 
		return ui.treeView->selectionModel()->selectedRows()[0].sibling(ui.treeView->selectionModel()->selectedRows()[0].row(), 1).data(0).toInt();
	}
	else 
		return -1;
}

void MainWindow::updatePath(int in_root, int flag)
{
	QString curMediumName, label, name;
	int parent_id = 0;
	QSqlQuery query;
	query.exec(QString("SELECT M.name FROM media M WHERE M.id='%1'").arg(currentMedium));
	if(query.next()) {
		curMediumName = query.value(0).toString();
	}

	if(in_root == 1) {
		ui.upButton->setDisabled(true);
		ui.pathLabel->setText(curMediumName.simplified() + ":/");
	}
	else {
		ui.upButton->setDisabled(false);
		switch(flag) {
			case -1:
				// cut the end of pathLabel
				label = ui.pathLabel->text();
				label.truncate( label.lastIndexOf("/", label.size()-2) + 1);
				ui.pathLabel->setText( label );
				break;
			case 0:
				// searching for the path in database
				query.exec(QString("SELECT F.parent_id, F.name FROM files F WHERE F.id='%1'").arg(currentFolder));
				if(query.next()) {
					parent_id = query.value(0).toInt();
					name = query.value(1).toString();
				}

				label = "/" + name + "/";
				while(parent_id != 0) {
					query.exec(QString("SELECT F.name, F.parent_id FROM files F WHERE F.id='%1'").arg(parent_id));
					if(query.next()) {
						label.prepend(query.value(0).toString());
						parent_id = query.value(1).toInt();
					}
				}
				label.prepend(curMediumName.simplified() + ":/");
				ui.pathLabel->setText(label);
				break;
			case 1:
				// go to current folder
				ui.pathLabel->setText(ui.pathLabel->text() + curFolderName + "/");
				break;
			default:
				// shouldn't ever happened
				break;
		}
	}
}

void MainWindow::goToParentFolder()
{
	QSqlQuery query;
	query.exec(QString("SELECT F.parent_id, F.in_root FROM files F WHERE F.id='%1'").arg(currentFolder));

	if(query.next()) {	
		updatePath(query.value(1).toInt(), -1);
		updateTableView(query.value(0).toInt(), 0);
	}
}

void MainWindow::setActiveDetailDock(QString location)
{
	if(location == "side") {
		activeDockDetail = ui.dockDetail2;
		activeTextInfo = ui.textInfo2;
		activeThumbnail = ui.thumbnail2;
		currentDockDetail = location;

		ui.dockDetail->setVisible(false);
		ui.dockDetail2->setVisible(true);

		//qDebug() << "splitter sizes: "<< ui.splitter->sizes()[0] << ui.splitter->sizes()[1] << ui.splitter->sizes()[2];
		if(ui.splitter->sizes()[2] == 0) {
			QList<int> splitterSizes;
			splitterSizes << ui.splitter->sizes()[0] << ui.splitter->sizes()[1] << 120;
			ui.splitter->setSizes(splitterSizes);
		}

		ui.actionMove_Detail_Dock->setText(tr("Put dock Details down"));
		ui.actionMove_Detail_Dock->setIcon(Images::icon("layout-down"));
	}
	else {
		// location == "down"
		activeDockDetail = ui.dockDetail;
		activeTextInfo = ui.textInfo;
		activeThumbnail = ui.thumbnail;
		currentDockDetail = location;
	
		ui.dockDetail2->setVisible(false);
		ui.dockDetail->setVisible(true);

		if(ui.splitter_2->sizes()[1] == 0) {
			QList<int> splitterSizes;
			splitterSizes << ui.splitter_2->sizes()[0] << 150;
			ui.splitter_2->setSizes(splitterSizes);
		}

		ui.actionMove_Detail_Dock->setText(tr("Put dock Details aside"));
		ui.actionMove_Detail_Dock->setIcon(Images::icon("layout-side"));
	}
}
